//
// Created by 11510 on 2024/6/15.
//

#include <regex>
#include "RssReader.h"
#include "tinyxml2.h"
using namespace tinyxml2;
using std::cout;
using std::endl;


RssItem::RssItem(const std::string &title, const std::string &link, const std::string &description,
                 const std::string &content) {
    /* 此处会拷贝 */
    this->title = title;
    this->link = link;
    this->description = description;
    this->content = content;
}

/**
 * 已弃用
 * @param input
 * @return
 */
string removeNestedTags(const string& input) {
    std::string output;
    bool inTag = false;
    for (char ch : input) {
        if (ch == '<') {
            inTag = true;
        } else if (ch == '>') {
            inTag = false;
        } else if (!inTag) {
            output += ch;
        }
    }

    /* 此处应该要返回拷贝，否则难以回收内存 */
    return output;
}

void RssReader::parseRss(const char* filename) {
    XMLDocument document;
    document.LoadFile(filename);
    XMLElement* root = document.RootElement();
    XMLElement* channel = root->FirstChildElement("channel");

    for(XMLElement* item = channel->FirstChildElement("item"); item; item = item->NextSiblingElement("item")) {
        XMLElement *title = item->FirstChildElement("title");
        XMLElement *link = item->FirstChildElement("link");
        XMLElement *description = item->FirstChildElement("description");
        XMLElement *content = item->FirstChildElement("content:encoded");

        /* 此处并未使用正则，description之中内容较少，不用正则反而好做 */
        string descriptionText = std::regex_replace(description->GetText(), std::regex(R"(<[^>]+>)"), "");
        string contentText = std::regex_replace(content->GetText(), std::regex(R"(<[^>]+>)"), "");

        /* 此处push的是指针，已无拷贝，但是构造会拷贝 */
        RssItem* rssItem = new RssItem(title->GetText(), link->GetText(), descriptionText, contentText);
//        printf("cap %d size %d\n", rss->capacity(), rss->size());
        rss->push_back(rssItem);
//        cout << contentText << endl;
    }
}


void insertChild(XMLDocument* page, XMLElement* parent, const char* elemName, const char* elemText){
    XMLElement* element = page->NewElement(elemName);
    XMLText* elementText = page->NewText(elemText);
    element->InsertEndChild(elementText);
    parent->InsertEndChild(element);
}


void RssReader::dump(const char* filename) {
    const char* declaration ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
    XMLDocument result;
    result.Parse(declaration);//会覆盖xml所有内容

    int cntDocumentId = 0;

    for(vector<RssItem*>::iterator it = rss->begin(); it != rss->end(); it++){
        XMLElement* doc = result.NewElement("doc");
        result.InsertEndChild(doc);

        /* it现在是指向指针的指针 */
        insertChild(&result, doc, "docid", std::to_string(cntDocumentId++).c_str());
        insertChild(&result, doc, "title", (*it)->link.c_str());
        insertChild(&result, doc, "link", (*it)->title.c_str());
        insertChild(&result, doc, "description", (*it)->description.c_str());
        insertChild(&result, doc, "content", (*it)->content.c_str());

    }

    result.SaveFile(filename);
}